﻿#pragma once

#include <list>
#include <vector>
#include <queue>
#include <string_view>
#include <array>
#include <mutex>
#include <unordered_map>
#include <shared_mutex>
#include <type_traits>
#include <ctime>

/*
这里auto都有含义
模板auto是用于enum类型
返回值auto,是用于寻找字符串,宏定义这个会记录整个函数命名
auto __cdecl EnumName<HELLOR>(void)
*/
template<auto T>
constexpr auto EnumName()
{
	std::string_view name;
#if __GNUC__ || __clang__
	name = __PRETTY_FUNCTION__;
	std::size_t start = name.find('=') + 2;
	std::size_t end = name.size() - 1;
	name = std::string_view{ name.data() + start, end - start };
	start = name.rfind("::");
#elif _MSC_VER
	name = __FUNCSIG__;
	std::size_t start = name.find('<') + 1;
	std::size_t end = name.rfind(">(");
	name = std::string_view{ name.data() + start, end - start };
	start = name.rfind("::");
#endif
	return start == std::string_view::npos ? name : std::string_view{
			name.data() + start + 2, name.size() - start - 2
	};
}

template<typename T, std::size_t N = 0>
constexpr auto EnumMax()
{
	constexpr auto value = static_cast<T>(N);
	if constexpr (EnumName<value>().find(")") == std::string_view::npos)
		return EnumMax<T, N + 1>();
	else
		return N;
}

template<typename T> requires std::is_enum_v<T>
constexpr auto EnumName(T value)
{
	constexpr auto num = EnumMax<T>();
	constexpr auto names = []<std::size_t... Is>(std::index_sequence<Is...>)
	{
		return std::array<std::string_view, num>
		{
			EnumName<static_cast<T>(Is)>()...
		};
	}(std::make_index_sequence<num>{});
	return names[static_cast<std::size_t>(value)];
}
